﻿// Copyright (c) egmkang wang. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace XServer.Grains
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.Contracts;
    using System.Threading.Tasks;
    using Orleans;
    using Orleans.Concurrency;
    using GrainInterfaces;
    using XServer.SDK;
    

    [Reentrant]
    public class GatewayGrain : Grain, IGatewayGrain
    {
        Dictionary<string, IGatewayObserver> listener = new Dictionary<string, IGatewayObserver>();

        public async override Task OnActivateAsync()
        {
            var grain = this.GrainFactory.GetGrain<IAllGatewayGrain>(0);
            Contract.Assert(grain != null, "Grain must be not null");
            await grain.RegisterGateway(this.GetPrimaryKeyString());
            await base.OnActivateAsync();
        }

        public async override Task OnDeactivateAsync()
        {
            var grain = this.GrainFactory.GetGrain<IAllGatewayGrain>(0);
            Contract.Assert(grain != null, "Grain must be not null");
            await grain.UnRegisterGateway(this.GetPrimaryKeyString());
            await base.OnDeactivateAsync();
        }

        public Task RecvMessage(ushort msgid, Immutable<byte[]> buffer)
        {
            throw new Exception("Gateway Dose not process client message");
        }

        public Task RegisterObserver(string key, IGatewayObserver ob)
        {
            if (this.listener.ContainsKey(key))
            {
                this.listener.Remove(key);
            }
            this.listener.Add(key, ob);
            return TaskDone.Done;
        }

        public Task UnRegisterObserver(string key)
        {
            this.listener.Remove(key);
            return TaskDone.Done;
        }

        public Task SendMessage(int destType, long dest, Immutable<byte[]> buffer)
        {
            foreach (var item in this.listener)
            {
                try
                {
                    item.Value.OnRecvMessage(destType, dest, buffer);
                }
                catch (Exception e)
                {
                    LoggerProvider.Logger.Error("Gateway.SendMessage, DestType:{0}, Dest:{1}, ErrorMessage:{2}"
                        , destType, dest, e.Message);
                }
            }
            return TaskDone.Done;
        }
    }
}
